package com.dreamfire.display.display2D
{
	import com.dreamfire.core.Client;
	import com.dreamfire.data.event.SceneEvent;
	import com.dreamfire.data.map.MapModel;
	import com.dreamfire.display.display2D.core.Sprite2D;
	import com.dreamfire.display.display2D.core.Tile2D;
	
	import flash.display.BitmapData;
	import flash.display.Sprite;
	import flash.geom.Matrix;
	import flash.geom.Rectangle;
	import flash.geom.Vector3D;
	import flash.utils.Dictionary;

	public class Camera2D
	{
		//----------------------------------------------------------------------------------------
		//
		//  Variable
		//
		//----------------------------------------------------------------------------------------
		private var _scene:Scene2D = null;
		private var _position:Vector3D = null;
		private var _zoom:Number = 1.0;
		private var _tileSize:uint;
		private var _rect:Rectangle = null;
		private var _viewPort:Viewport2D = null;
		
		private var _spriteList:Dictionary = new Dictionary(true);
		private var _mapTileList:Array = [];
		private var _mapContainer:Sprite;
		
		//----------------------------------------------------------------------------------------
		//
		//  Constructor
		//
		//----------------------------------------------------------------------------------------
		public function Camera2D(width:Number, height:Number, scene:Scene2D = null, viewPort:Viewport2D = null, position:Vector3D = null, tileSize:uint = 32)
		{
			_scene = scene || new Scene2D();
			_position = position || new Vector3D();
			_tileSize = tileSize;
			_viewPort = viewPort;
			_mapContainer = new Sprite();
			_rect = new Rectangle(0, 0, width, height);
			Client.instance.eventDispatcher.addEventListener(SceneEvent.MAP_UPDATE, mapUpdate);
		}
		
		//----------------------------------------------------------------------------------------
		//
		//  Setter & Getter
		//
		//----------------------------------------------------------------------------------------
		/**
		 * 地图的网格
		 */
		public function get mapTileList():Array
		{
			return _mapTileList;
		}
		public function set mapTileList(value:Array):void
		{
			_mapTileList = value;
		}

		/**
		 * 地图上的精灵
		 */
		public function get spriteList():Dictionary
		{
			return _spriteList;
		}
		public function set spriteList(value:Dictionary):void
		{
			_spriteList = value;
		}

		/**
		 * 网格的大小
		 */
		public function get tileSize():uint
		{
			return _tileSize;
		}
		public function set tileSize(value:uint):void
		{
			_tileSize = value;
		}
		
		/**
		 * 视窗口高度
		 */
		public function get height():Number
		{
			return _rect.height;
		}
		public function set height(value:Number):void
		{
			_rect.height = uint(value);
			cameraSizeChanged();
		}
		
		/**
		 * 视窗口宽度
		 */
		public function get width():Number
		{
			return _rect.width;
		}
		public function set width(value:Number):void
		{
			_rect.width = uint(value);
			cameraSizeChanged();
		}
		
		/**
		 * 缩放
		 */
		public function get zoom():Number
		{
			return _zoom;
		}
		public function set zoom(value:Number):void
		{
			_zoom = value;
		}
		
		/**
		 * 坐标
		 */
		public function get position():Vector3D
		{
			return _position;
		}
		public function set position(value:Vector3D):void
		{
			_position = value;
			positionChanged();
		}
		
		/**
		 * 场景的引用
		 */
		public function get scene():Scene2D
		{
			return _scene;
		}
		public function set scene(value:Scene2D):void
		{
			_scene = value as Scene2D;
		}
		
		//----------------------------------------------------------------------------------------
		//
		//  Performance
		//
		//----------------------------------------------------------------------------------------
		
		/**
		 * 在更换地图以后重新生成地图瓦片
		 */
		public function mapUpdate(event:SceneEvent):void
		{
			_mapTileList = [];
			_mapContainer.removeChildren();
			var hn:int = MapModel.curMap.hTilenum;
			var vn:int = MapModel.curMap.vTilenum;
			for( var i:int = 0; i < hn; i++ )
			{
				for( var j:int = 0; j < vn; j++ )
				{
					var tile:Tile2D = new Tile2D( MapModel.curMap.tileSize );
					tile.position = new Vector3D( i * tile.size, 0, j * tile.size );
					tile.loadResource( MapModel.curMap.id, i, j );
					_mapTileList.push( tile );
					_mapContainer.addChild( tile );
				}
			}
		}

		/**
		 * 每帧对镜头内数据更新，坐标调整，渲染物件剔除，及最后渲染
		 * 
		 */
		public function update():void
		{
			positionTransform();
			eliminate();
		}
		
		/**
		 * 场景物品对应镜头坐标转换
		 * @return 
		 * 
		 */
		public function positionTransform():void
		{
			//将场景内物品的坐标转换至镜头坐标系
			for each( var sp:Sprite2D in scene.spriteList )
			{
				sp.x = sp.position.x - position.x;
				sp.y = sp.position.z - position.z;
				spriteList[sp] = sp;
			}
		}
		
		/**
		 * 获取当前地图区域的图像
		 */
		public function getMapBmp():BitmapData
		{
			var bmpd:BitmapData = new BitmapData( _rect.width, _rect.height );
			var dx:Number = position.x;
			var dy:Number = position.z;
			var m:Matrix = new Matrix();
			m.translate( -dx, -dy );
			bmpd.draw( _mapContainer, m, null, null, _rect );
			return bmpd;
		}
		
		/**
		 * 剔除
		 * 
		 */
		public function eliminate():void
		{
			//对镜头外不需要显示的地图面及精灵在镜头显示列表中剔除
			for each( var sp:Sprite2D in spriteList )
			{
				if( sp.x + sp.width < 0 ||
					sp.x - sp.width > width ||
					sp.y + sp.height < 0 ||
					sp.y - sp.height > height )
					spriteList[sp] = null;
				else
					spriteList[sp] = sp;
			}
		}
		
		/**
		 * 镜头坐标被改变
		 */
		protected function positionChanged():void
		{
			
		}
		
		/**
		 * 摄像机的尺寸被改变
		 */
		protected function cameraSizeChanged():void
		{
			
		}
	}
}